package com.cargo.base.utils;

import com.cargo.base.apo.length;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class CommonValidate {
	/**
	 * 验证对象各属性长度是否合法
	 * 
	 * @param obj
	 * @return Map<String, String>,key:不合法的字段名，value:不合法的描述 <br/>
	 *         其中：key="code"时,value=1为验证成功，value=0为验证失败
	 * @throws Exception
	 */
	public static Map<String, String> validate(Object obj) throws Exception {
		Map<String, String> result = new HashMap<String, String>();
		result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.success.code"));
		Field[] fields = getFields(obj);
		for (Field f : fields) {
			String name = f.getName();
			Annotation annotation = f.getAnnotation(length.class);
			if (annotation != null) {
				length len = (length) annotation;
				Object value = obj.getClass()
						.getMethod("get" + String.valueOf(name.charAt(0)).toUpperCase() + name.substring(1), (Class<?>[]) null)
						.invoke(obj, new Object[0]);
				String validateName = StringUtils.isBlank(len.name()) ? name : len.name();
				if (len.required()) {
					if (value == null) {
						result.put(validateName, PropertiesUtil.getValue("common.msg.notempty"));
						result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.fail.code"));
					} else {
						int realLen = value.toString().length();
						if (realLen < len.min()) {
							result.put(validateName, PropertiesUtil.getValue("common.msg.lesslength"));
							result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.fail.code"));
						}
						if (realLen > len.max()) {
							result.put(validateName, PropertiesUtil.getValue("common.msg.morelength"));
							result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.fail.code"));
						}
						if((StringUtils.isNotBlank(len.rule())) && !value.toString().matches(len.rule())){
							result.put(name, PropertiesUtil.getValue("common.msg.errorformat"));
							result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.fail.code"));
						}
					}
				} else {
					if (value == null) {
					} else {
						int realLen = value.toString().length();
						if (realLen < len.min()) {
							result.put(validateName, PropertiesUtil.getValue("common.msg.lesslength"));
							result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.fail.code"));
						}
						if (realLen > len.max()) {
							result.put(validateName, PropertiesUtil.getValue("common.msg.morelength"));
							result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.fail.code"));
						}
						if((StringUtils.isNotBlank(len.rule())) && !value.toString().matches(len.rule())){
							result.put(validateName, PropertiesUtil.getValue("common.msg.errorformat"));
							result.put(PropertiesUtil.getValue("common.validate.code"), PropertiesUtil.getValue("common.fail.code"));
						}
					}
				}
			}
		}
		return result;
	}

	private static Field[] getFields(Object obj) {
		return getAll(obj, obj.getClass());
	}

	private static Field[] getAll(Object obj, Class<? extends Object> clazz) {
		Field[] result;
		Field[] fields = clazz.getDeclaredFields();
		if (!"java.lang.Object".equals(clazz.getSuperclass().getName())) {
			Field[] fields2 = getAll(obj, obj.getClass().getSuperclass());
			result = (Field[]) ArrayUtils.addAll(fields, fields2);
		} else {
			result = fields;
		}
		return result;
	}

	public static void main(String[] args) throws Exception {
//		ShiroUser user = new ShiroUser();
//		user.setUserName("12345678901");
//		Map<String, String> map = validate(user);
//		if ("1".equals(map.get("returncode"))) {
//			System.out.println("验证通过");
//		} else {
//			System.out.println("验证不通过,返回map");
//		}
	}
}
